// SPDX-License-Identifier: GPL-2.0 or GPL-3.0
// Copyright © 2018-2019 Ariadne Devos
/* sHT -- select a proessor-supported vector size */

#include <sHT/vector.h>
#include <sHT/bugs.h>

#ifndef sHT_single_vector

/** The binary logarithm of the largest vector size */
static int sHT_vector_order;

size_t
sHT_select_simd(int elem_order)
{
	int relative = sHT_vector_order - elem_order;
	sHT_require(relative >= 0);
	return relative;
}

/* Compare with <sHT/vector.h> */

# ifdef __x86_64__
void
sHT_detect_simd(void)
{
	__builtin_cpu_init();
	if (__builtin_cpu_supports("avx512f"))
		sHT_vector_order = 6;
	else if (__builtin_cpu_supports("avx2"))
		sHT_vector_order = 5;
	else sHT_vector_order = 4;
}
# elif defined(__i386__)
void
sHT_detect_simd(void)
{
	__builtin_cpu_init();
	if (__builtin_cpu_supports("avx512f"))
		sHT_vector_order = 6;
	else if (__builtin_cpu_supports("avx2"))
		sHT_vector_order = 5;
	else if (__builtin_cpu_supports("sse2"))
		sHT_vector_order = 4;
	else if (__builtin_cpu_supports("mmx"))
		sHT_vector_order = 3;
	else sHT_vector_order = 2;
}
# elif defined(__arm__)
#  include <sys/auxv.h>
void
sHT_detect_simd(void)
{
	if (getauxval(AT_HWCAP) & HWCAP_ARM_NEON)
		sHT_vector_order = 4;
	else sHT_vector_order = 2;
}
# else
#  error unsupported system, inconsistency with <sHT/vector.h>
# endif
#endif
